package com.hnkywl.sts.action.flow;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.hnkywl.sts.entity.sys.Yg;
import com.hnkywl.sts.service.base.DxpzService;
import com.hnkywl.sts.service.flow.FlowService;
import com.hnkywl.sts.service.jhgl.XyService;
import com.hnkywl.sts.service.sys.YgService;
import com.hnkywl.sts.util.BaseUtils;
import net.ruixin.orm.hibernate.Page;
import net.ruixin.web.struts2.SimpleActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.jbpm.api.*;
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.model.ActivityCoordinates;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
import java.util.zip.ZipInputStream;

/**
 * Created with IntelliJ IDEA.
 * User: jerry
 * Date: 13-4-7
 * Time: 上午10:10
 * To change this template use File | Settings | File Templates.
 */
@Namespace("/flow/publish")
public class PublishAction extends SimpleActionSupport {
    private RepositoryService repositoryService;

    private ExecutionService executionService;

    private HistoryService historyService;

    private FlowService flowService;

    private DxpzService dxpzService;

    private YgService ygService;

    private String deploymentId;

    private String name;

    private String url;

    //分页组件 起始位置
    private int page;
    //分页组件 页面大小
    private int rows;

    private List<ActivityCoordinates> acList = new ArrayList<ActivityCoordinates>();

    private String processInstanceId;

    private String processDefinitionId;

    private List<ProcessDefinition> processDefinitionList;

    private String result;

    private String taskId;

    private String lc_name;

    private String businessNo;

    private String ygidstr;

    private String opera;

    private String time;

    private String executionId;

    @Action("publishFlow")
    public void publish() {
        processDefinitionList = repositoryService.createProcessDefinitionQuery().page((page - 1)*rows, rows).orderAsc(ProcessDefinitionQuery.PROPERTY_ID).list();
        String lcJson = BaseUtils.fetchCollectionToJson(processDefinitionList, "id", "name", "version", "deploymentId", "key");
        this.renderJson("{\"total\":" + repositoryService.createProcessDefinitionQuery().count() + ",\"rows\":[" + lcJson + "]}");
    }

    @Action(value = "deploy")
    public void deploy() {
        String path = "flowResources/_Flow/_Process.zip";
        path = path.replaceAll("_", this.lc_name);
        ZipInputStream zip = new ZipInputStream(this.getClass().getClassLoader().getResourceAsStream(path));
        repositoryService.createDeployment().addResourcesFromZipInputStream(zip).deploy();
        renderText("{\"statusCode\":\"200\", \"message\":\"添加流程成功\"}");
    }

    @Action(value = "delProcess")
    public void delProcess() {
        repositoryService.deleteDeploymentCascade(this.deploymentId);
        renderText("{\"statusCode\":\"200\", \"message\":\"删除流程成功\"}");
    }

    @Action("ownerTask")
    public void findOwnerTask() {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();

        List<Map> list = this.flowService.findOwnerTask(YgService.getCurrentYg().getId());
        String lcJson = gson.toJson(list);
        this.renderJson("{\"total\":" + list.size() + ",\"rows\":" + lcJson + "}");
    }

    @Action("ownerHistory")
    public void findOwnerHistory() {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
        Page list = this.flowService.findOwnerHistory(page, rows);
        String lcJson = gson.toJson(list.getResult());
        this.renderJson("{\"total\":" + list.getTotalCount() + ",\"rows\":" + lcJson + "}");
    }

    @Action("taskDetail")
    public String taskDetail() {
        return SUCCESS;
    }


    @Action("flowPicture")
    public String viewPic() {
        ProcessInstance pi = null;
        try {
            pi = this.executionService.findProcessInstanceById(URLDecoder.decode(this.processInstanceId, "UTF-8"));
            if (pi != null) {
                this.processDefinitionId = URLEncoder.encode(URLEncoder.encode(pi.getProcessDefinitionId(), "UTF-8"), "UTF-8");
                Set<String> activityNames = pi.findActiveActivityNames();
                for (String activityName : activityNames) {
                    acList.add(this.repositoryService.getActivityCoordinates(pi.getProcessDefinitionId(), activityName));
                }
            } else {
                HistoryProcessInstance hpi = this.historyService.createHistoryProcessInstanceQuery().processInstanceId(URLDecoder.decode(this.processInstanceId, "UTF-8")).uniqueResult();
                this.processDefinitionId = URLEncoder.encode(URLEncoder.encode(hpi.getProcessDefinitionId(), "UTF-8"), "UTF-8");
            }
            this.processInstanceId = URLEncoder.encode(this.processInstanceId, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    @Action("picture")
    public String picture() {
        String id = null;
        try {
            id = URLDecoder.decode(this.request.getParameter("id"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(id).uniqueResult();
        InputStream inputStream = this.repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), "process.png");
        byte[] b = new byte[1024];
        int len = -1;
        try {
            while ((len = inputStream.read(b, 0, 1024)) != -1) {
                this.response.getOutputStream().write(b, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Action("historyFlow")
    public void historyFlow() {
        try {
            List<Object[]> historyList = this.flowService.findHistory(URLDecoder.decode(this.processInstanceId, "UTF-8"));

            List<Map<String, Object>> valueList = new ArrayList<Map<String, Object>>();
            Map<String, Object> map = new HashMap<String, Object>();
            for (Object[] obj : historyList) {
                if (map.size() == 4) {
                    map = new HashMap<String, Object>();
                }
                if (!obj[0].equals("owner")) {
                    if (obj[0].equals("time"))
                        obj[1] = obj[1].toString().substring(0, obj[1].toString().indexOf(","));
                    map.put(obj[0].toString(), obj[1]);
                }

                if (map.size() == 4) {
                    valueList.add(map);
                }
            }
            valueList.add(map);
            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
            String json = gson.toJson(valueList);
            StringBuilder s = new StringBuilder("{\"rows\":");
            s.append(json).append("}");
            this.renderJson(s.toString());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    @Action("msgUser")
    public void msgUser() {
        try {
            List<Yg> ygList = this.flowService.findMsgUser(URLDecoder.decode(this.processInstanceId, "UTF-8"));
            String ygJson = BaseUtils.fetchCollectionToJson(ygList, "id", "gh", "dlm", "xm", "zgjg.qc", "zygw.mc", "kdl", "sfzz", "cwbh", "rzsj", "dhhm", "zssj.xm", "cxfw", "kmdm");
            this.renderJson("{\"rows\":[" + ygJson + "]}");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    @Action("sendMsg")
    public void sendMsg() {
        try {
            String[] ygids = ygidstr.split(",");
            List<Yg> ygList = new ArrayList<Yg>();
            for (String ygid : ygids) {
                Yg yg = this.ygService.findYgDetail(Long.parseLong(ygid));
                ygList.add(yg);
            }
            String lcmc= URLDecoder.decode(URLDecoder.decode(this.executionId, "UTF-8"),"UTF-8");
            lcmc = lcmc.substring(0, lcmc.indexOf("-"));
            this.dxpzService.sendMsgForFlow(ygList, lcmc, businessNo, opera, time);
            renderText("{\"statusCode\":\"200\", \"message\":\"短信发送成功！\", \"operationType\":\"delete\"}");
        } catch (Exception e) {
            e.printStackTrace();
            renderText("{\"statusCode\":\"300\", \"message\":\"" + e.getMessage() + "\"}");
        }
    }

    public List<ProcessDefinition> getProcessDefinitionList() {
        return processDefinitionList;
    }

    public void setProcessDefinitionList(List<ProcessDefinition> processDefinitionList) {
        this.processDefinitionList = processDefinitionList;
    }

    public String getDeploymentId() {
        return deploymentId;
    }

    public void setDeploymentId(String deploymentId) {
        this.deploymentId = deploymentId;
    }

    public RepositoryService getRepositoryService() {
        return repositoryService;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getProcessInstanceId() {
        return processInstanceId;
    }

    public void setProcessInstanceId(String processInstanceId) {
        this.processInstanceId = processInstanceId;
    }

    public String getProcessDefinitionId() {
        return processDefinitionId;
    }

    public void setProcessDefinitionId(String processDefinitionId) {
        this.processDefinitionId = processDefinitionId;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public List<ActivityCoordinates> getAcList() {
        return acList;
    }

    public void setAcList(List<ActivityCoordinates> acList) {
        this.acList = acList;
    }

    public String getLc_name() {
        return lc_name;
    }

    public void setLc_name(String lc_name) {
        this.lc_name = lc_name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getBusinessNo() {
        return businessNo;
    }

    public void setBusinessNo(String businessNo) {
        this.businessNo = businessNo;
    }

    public String getYgidstr() {
        return ygidstr;
    }

    public void setYgidstr(String ygidstr) {
        this.ygidstr = ygidstr;
    }

    public String getOpera() {
        return opera;
    }

    public void setOpera(String opera) {
        this.opera = opera;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getExecutionId() {
        return executionId;
    }

    public void setExecutionId(String executionId) {
        this.executionId = executionId;
    }

    @Autowired
    public void setFlowService(FlowService flowService) {
        this.flowService = flowService;
    }

    @Autowired
    public void setRepositoryService(@Qualifier("repositoryService") RepositoryService repositoryService) {
        this.repositoryService = repositoryService;
    }

    @Autowired
    public void setExecutionService(@Qualifier("executionService") ExecutionService executionService) {
        this.executionService = executionService;
    }

    @Autowired
    public void setHistoryService(@Qualifier("historyService") HistoryService historyService) {
        this.historyService = historyService;
    }

    @Autowired
    public void setDxpzService(DxpzService dxpzService) {
        this.dxpzService = dxpzService;
    }

    @Autowired
    public void setYgService(YgService ygService) {
        this.ygService = ygService;
    }
}
